/**
 * $RCSfile: GooglePlugin.java,v $
 * $Revision: 1.1 $
 * $Date: 2010/06/30 07:39:02 $
 *
 * Copyright (C) 1999-2005 Jive Software. All rights reserved.
 *
 * This software is the proprietary information of Jive Software. Use is
 subject to license terms.
 */

package cn.newgrand.netcall.integration;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;

import org.jivesoftware.resource.Res;
import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.packet.DelayInformation;
import org.jivesoftware.smackx.packet.VCard;
import org.jivesoftware.spark.ChatManager;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.Workspace;
import org.jivesoftware.spark.component.RolloverButton;
import org.jivesoftware.spark.plugin.ContextMenuListener;
import org.jivesoftware.spark.plugin.Plugin;
import org.jivesoftware.spark.ui.ChatContainer;
import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.ui.ChatRoomButton;
import org.jivesoftware.spark.ui.ChatRoomListenerAdapter;
import org.jivesoftware.spark.ui.ChatRoomNotFoundException;
import org.jivesoftware.spark.ui.CommandPanel;
import org.jivesoftware.spark.ui.ContactGroup;
import org.jivesoftware.spark.ui.ContactItem;
import org.jivesoftware.spark.ui.ContactList;
import org.jivesoftware.spark.ui.MessageListener;
import org.jivesoftware.spark.ui.TranscriptWindow;
import org.jivesoftware.spark.ui.rooms.ChatRoomImpl;
import org.jivesoftware.spark.util.SwingWorker;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.plugin.alerts.SparkToaster;
import org.jivesoftware.sparkimpl.plugin.transcripts.HistoryMessageManager;
import org.jivesoftware.sparkimpl.preference.sounds.SoundPreference;
import org.jivesoftware.sparkimpl.profile.VCardListener;
import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;
import org.jivesoftware.sparkimpl.settings.local.SettingsManager;

import cn.newgrand.netcall.common.MesType;
import cn.newgrand.netcall.integration.menu.AppSysPanel;
import cn.newgrand.netcall.integration.message.AppSysToaster;
import cn.newgrand.netcall.integration.setting.SettingPreference;
import cn.newgrand.netcall.integration.sms.ContactsPresenceListener;
import cn.newgrand.netcall.integration.sms.PhoneBindingPanel;
import cn.newgrand.netcall.integration.sms.SMSManager;
import cn.newgrand.netcall.integration.sms.SendSMSDecorator;
import cn.newgrand.netcall.smackx.integration.AppSysBindPhoneIQ;
import cn.newgrand.smackx.packet.AppSysIQ;
import cn.newgrand.smackx.packet.AppSysMes;
import cn.newgrand.netcall.smackx.integration.AppSysOfflineDateIQ;
import cn.newgrand.netcall.transcript.ChatTranscript;
import cn.newgrand.netcall.transcript.HistoryMessage;

public class AppSysMesPlugin implements Plugin,PacketListener,VCardListener{
	private SettingPreference settingPreference;
	public static final String APP_SYS_MES_FILE_NAME = "appsys";
	private static int appBatchCount = 0;
	private HistoryMessage lastMessage = null;
	private List<HistoryMessage> list = new ArrayList<HistoryMessage>();
	public static ChatTranscript ct = new ChatTranscript();
	private final AppSysPanel asp = new AppSysPanel();
	private final RolloverButton emailButton = new RolloverButton(AppSysRes.getImageIcon(AppSysRes.INTEGRATION_EMAIL));
	final RolloverButton appSysButton = new RolloverButton(AppSysRes.getImageIcon(AppSysRes.INTEGRATION_IMAGE));
	
	private SMSManager smsManager = SMSManager.getInstance();
	
//	public final static Map<String,String> prb = new HashMap<String, String>();
	
	private final int clearChatTranscriptTime = 10000;//前后两次消息间隔毫秒数,大于该毫秒数则清除消息副本
	private final int checkShowToasterPeriod = 50000;//检查是否有消息，并显示提示框的时间间隔毫秒数
	
	private long diff = 0;
	
	private boolean isLoadFinished = false;
		
    public void initialize() {
    	//判断是坐席登录不初始化插件
    	LocalPreferences preferences = SettingsManager.getLocalPreferences();
        if(preferences.isPublicLogin()){
        	return;
        }
    	ProviderManager.getInstance().addExtensionProvider("x","jabber:x:appsys", new AppSysMes.Provider());
    	ProviderManager.getInstance().addIQProvider("query", "jabber:iq:appsys", new AppSysIQ.Provider());
    	ProviderManager.getInstance().addIQProvider("query", "ng:iq:appsysbindphone", new AppSysBindPhoneIQ.Provider());
    	ProviderManager.getInstance().addIQProvider("query", "ng:iq:appsysofflinedate", new AppSysOfflineDateIQ.Provider());
    	
    	IntegrationManager.initPreference();
    	settingPreference = IntegrationManager.getSettingPreference();
    	
    	asp.initialize();
    	loadServerProperties();
    	
    	AppSysToaster toaster = new AppSysToaster();
        final JMenu actionsMenu = SparkManager.getMainWindow().getMenuByName(Res.getString("menuitem.actions"));
        JMenuItem appMessageMenu = new JMenuItem("待办任务", AppSysRes.getImageIcon(AppSysRes.INTEGRATION_IMAGE));
        JMenuItem appOpenSMSMenu = new JMenuItem("手机绑定", AppSysRes.getImageIcon(AppSysRes.INTEGRATION_IMAGE));
        emailButton.setToolTipText("邮件系统");
        appSysButton.setToolTipText("登入应用系统");
        
        CommandPanel cp = SparkManager.getWorkspace().getCommandPanel();
        cp.add(emailButton);
        cp.add(appSysButton);
        cp.validate();
        cp.invalidate();
        cp.repaint();
        
        initSMS();
        
        
        ActionListener appSysButtonAction = new ActionListener() {
        	@Override
        	public void actionPerformed(ActionEvent e) {
        		if(isLoadFinished){
        			IntegrationManager.getWinInteraction().loginAppSys(null);
        		}
        	}
        };
        
        appSysButton.addActionListener(appSysButtonAction);
        ActionListener emailButtonAction = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if(isLoadFinished){
					IntegrationManager.getWinInteraction().loginAppSys(AppSysRes.getString(AppSysRes.APP_FUNCITON_URL_EMAIL));
					emailButton.setText("");
				}
			}
		};
        
		emailButton.addActionListener(emailButtonAction);
        
//        ResourceUtils.resButton(appMessageMenu, "应用系统消息");
        actionsMenu.add(appMessageMenu);
        
        appMessageMenu.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            	cn.newgrand.netcall.transcript.HistoryMessageManager.getInstance().showAppHistory(ct);
            	
            }
        });
        
        actionsMenu.add(appOpenSMSMenu);
        
        appOpenSMSMenu.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				new PhoneBindingPanel();
			}
		});
        
     // Load Version
        
        PacketFilter serverFilter = new PacketTypeFilter(Message.class);
        SparkManager.getConnection().addPacketListener(this, serverFilter);
        SparkManager.getVCardManager().addVCardListener(this);
        Workspace ws = SparkManager.getWorkspace();
        
        if(ws.appOfflineCount!=0){
        	toaster.setDisplayTime(30000);
        	toaster.setTitle(Res.getString("title.notification"));
        	toaster.showToaster("您有"+ws.appOfflineCount+"条任务需要处理");
        	ws.appOfflineCount = 0;
        }
        
        final Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				if(0!=appBatchCount){
					AppSysToaster batchToaster = new AppSysToaster();
					batchToaster.setDisplayTime(30000);
					batchToaster.setTitle(Res.getString("title.notification"));
					batchToaster.showToaster();
		        	appBatchCount = 0;
				}
			}
		}, 20000, checkShowToasterPeriod);
    }
    
    /**
     * 
     * 加载集成其他应用程序的配置信息(i6,a3等)
     *  包括构建常用功能菜单
     */
    public void loadServerProperties(){
         final AppSysIQ appSysRequest = new AppSysIQ();
         
         appSysRequest.setType(IQ.Type.GET);
         appSysRequest.setTo("integration." + SparkManager.getConnection().getServiceName());
         final PacketCollector collector = SparkManager.getConnection().createPacketCollector(new PacketIDFilter(appSysRequest.getPacketID()));

         SwingWorker appSysThread = new SwingWorker() {
             IQ result;

             public Object construct() {
                 SparkManager.getConnection().sendPacket(appSysRequest);
//                 result = (IQ)collector.nextResult(5000);
                 result = (IQ)collector.nextResult(300*1000);
                 return result;
             }

             public void finished() {
                 // Wait up to 30 seconds for a result.
            	 
                 if (result != null && result.getType() == IQ.Type.RESULT) {
                 	AppSysIQ appResult = (AppSysIQ)result;
                 	AppSysRes.serverPrb.putAll(appResult.getProperties());
                 	
                 	if(null!=appResult.getProperties().get(AppSysRes.APP_USER_MENU_FUNC)){
                 		asp.buildMenuList();
                 	}
                 	
                 	String temp = appResult.getProperties().get(AppSysRes.APP_SMS_ISAVAILABLE);
                 	if(null!=temp){
                 		SMSManager.isSMSServerAvailable = Boolean.valueOf(temp);
                 	}
                 	String isGrant = appResult.getProperties().get("integration.ng.sms.isgrantsendsms");
                 	if("true".equals(isGrant)){
                 		SMSManager.isGrantSendSMS = true;
                 	}else{
                 		SMSManager.isGrantSendSMS = false;
                 	}
                 	SMSManager.bindPhone = appResult.getProperties().get("integration.ng.sms.bindphone");
                 }
                 //settingPreference.loadFromFile();
                 //settingPreference.loadFromProperties();
                 isLoadFinished = true;
             }
         };
         appSysThread.start();
    }
    
    /**
     * 处理接收到的包
     */
    @Override
    public void processPacket(final Packet packet) {
    	SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    final Message message = (Message)packet;
                    HistoryMessage hm = new HistoryMessage();
                    Date nowDate = new Date();
                    //如果是业务系统消息这里也不做处理
                    final DelayInformation offlineInformation = (DelayInformation)message.getExtension("x", "jabber:x:delay");
                    String filename = "appsys";
                    AppSysMes appSysMes = (AppSysMes)message.getExtension("x","jabber:x:appsys");
                    if(message.getError() == null&&null!=appSysMes){
						if (MesType.isTaskMes(appSysMes.getType())) {
							appBatchCount++;
							if (null == lastMessage) {
								lastMessage = new HistoryMessage();
								lastMessage.setDate(nowDate);
							}
							diff = nowDate.getTime()
									- lastMessage.getDate().getTime();
							if (diff > clearChatTranscriptTime) {
								ct.getMessages().clear();
							}
							messageToTranscript(message);
							lastMessage.setDate(nowDate);
						}else if(MesType.isEmailCountMes(appSysMes.getType())){
							emailButton.setText(message.getBody().trim());
						}
                    }
                    
                }
                catch (Exception e) {
                    Log.error(e);
                }
            }
        });
    }
    public ChatTranscript getChatTranscript(){
    	return ct;
    }
    
    public void messageToTranscript(Message message){
//		ChatTranscript transcript = new ChatTranscript();
		HistoryMessage history = new HistoryMessage();
        history.setTo(message.getTo());
        history.setFrom(message.getFrom());
        history.setBody(message.getBody());
        Date date = (Date)message.getProperty("date");
        if (date != null) {
            history.setDate(date);
        }
        else {
            history.setDate(new Date());
        }
        ct.addHistoryMessage(history);
//        return transcript;
	}
    
    /**
     * Show Server Alert.
     *
     * @param message the message to show.
     */
    private void showAlert(Message message) {
        // Do not show alert if the message is an error.
        if (message.getError() != null) {
            return;
        }

        final String body = message.getBody();
        String subject = message.getSubject();

        StringBuffer buf = new StringBuffer();
        if (subject != null) {
            buf.append(Res.getString("subject")).append(": ").append(subject);
            buf.append("\n\n");
        }

        buf.append(body);

        String from = message.getFrom() != null ? message.getFrom() : "";

        final TranscriptWindow window = new TranscriptWindow();
        window.insertPrefixAndMessage(null, buf.toString(), ChatManager.TO_COLOR);

        JPanel p = new JPanel();
        p.setLayout(new BorderLayout());
        p.add(window, BorderLayout.CENTER);
        p.setBorder(BorderFactory.createLineBorder(Color.lightGray));


        SparkToaster toaster = new SparkToaster();
        toaster.setDisplayTime(30000);
        toaster.setBorder(BorderFactory.createBevelBorder(0));


        if (!from.contains("@")) {
            ChatManager chatManager = SparkManager.getChatManager();
            ChatContainer container = chatManager.getChatContainer();

            ChatRoomImpl chatRoom;
            try {
                chatRoom = (ChatRoomImpl)container.getChatRoom(from);
            }
            catch (ChatRoomNotFoundException e) {
                chatRoom = new ChatRoomImpl("serveralert@" + from, Res.getString("broadcast"), Res.getString("broadcast"));
                chatRoom.getBottomPanel().setVisible(false);
                chatRoom.getToolBar().setVisible(false);
                SparkManager.getChatManager().getChatContainer().addChatRoom(chatRoom);
            }


            chatRoom.insertMessage(message);
//            broadcastRooms.add(chatRoom);
        }
        else if (message.getFrom() != null) {
            String jid = StringUtils.parseBareAddress(from);
            String nickname = SparkManager.getUserManager().getUserNicknameFromJID(jid);
            ChatManager chatManager = SparkManager.getChatManager();
            ChatContainer container = chatManager.getChatContainer();

            ChatRoomImpl chatRoom;
            try {
                chatRoom = (ChatRoomImpl)container.getChatRoom(jid);
            }
            catch (ChatRoomNotFoundException e) {
                chatRoom = new ChatRoomImpl(jid, nickname, nickname);
                SparkManager.getChatManager().getChatContainer().addChatRoom(chatRoom);
            }

            chatRoom.insertMessage(message);
//            broadcastRooms.add(chatRoom);

            chatRoom.addMessageListener(new MessageListener() {
                boolean waiting = true;

                public void messageReceived(ChatRoom room, Message message) {
                    removeAsBroadcast(room);
                }

                public void messageSent(ChatRoom room, Message message) {
                    removeAsBroadcast(room);
                }

                private void removeAsBroadcast(ChatRoom room) {
                    if (waiting) {
//                        broadcastRooms.remove(room);

                        // Notify decorators
                        SparkManager.getChatManager().notifySparkTabHandlers(room);
                        waiting = false;
                    }
                }
            });
        }
    }
    
    /**
     * 初始化SMS插件
     */
    private void initSMS(){
    	addSendSMSButton();
    	addSMSPopupListeners();
    	addItemToMenu();
    	addRosterListener();
    }
    
	private void addRosterListener() {
		//用户有发短信权限的则统计其他用户的离线时间
//		if(SMSManager.isGrantSendSMS){
			SparkManager.getConnection().getRoster().addRosterListener(new ContactsPresenceListener());
//		}
	}

	/**
     * 添加短信历史记录到菜单
     */
    private void addItemToMenu(){
    	 final JMenu actionsMenu = SparkManager.getMainWindow().getMenuByName(Res.getString("menuitem.actions"));
    	//添加广播历史记录
        JMenuItem viewHistoryItem = new JMenuItem(Res
    			.getString("menuitem.view.sms.history"), SparkRes
    			.getImageIcon(SparkRes.SMS_HISTORY));
        actionsMenu.add(viewHistoryItem);
        
        viewHistoryItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if(SMSManager.isGrantSendSMS){
					final String filename = "sms";
					HistoryMessageManager.getInstance().showBroadcastHistory(filename);
				}else{
					JOptionPane.showMessageDialog(SparkManager.getMainWindow(), "您未被授予发短信的权限,请通知管理员配置.", "权限不足", JOptionPane.INFORMATION_MESSAGE);
				}
			}
		});
    }
    
    /**
     * 聊天窗添加短信按钮
     */
    private void addSendSMSButton() {
        final ChatManager chatManager = SparkManager.getChatManager();
        chatManager.addChatRoomListener(new ChatRoomListenerAdapter() {

            public void chatRoomOpened(final ChatRoom room) {
            	final Set<String> jids = new HashSet<String>();
				if (room instanceof ChatRoomImpl) {
					final ChatRoomImpl crImpl = (ChatRoomImpl)room;
					final ChatRoomButton smsButton = new ChatRoomButton("", SparkRes.getImageIcon(SparkRes.SMS_SEND_TO_ONE_24x24));
					smsButton.setToolTipText(Res.getString("tolltip.send.sms"));
					crImpl.getToolBar().addChatRoomButton(smsButton);
					smsButton.addActionListener(new ActionListener() {
						@Override
						public void actionPerformed(ActionEvent e) {
							if(SMSManager.isGrantSendSMS){
								jids.add(crImpl.getParticipantJID());
								smsManager.handleSMSDialog(jids);
							}else{
								JOptionPane.showMessageDialog(room, "您未被授予发短信的权限,请通知管理员配置.", "权限不足", JOptionPane.INFORMATION_MESSAGE);
							}
							
						}
					});
					//聊天窗口添加同时发送短信复选框
					new SendSMSDecorator(crImpl);
				}
            }

            public void chatRoomClosed(ChatRoom room) {

            }
        });
    }
    
    /**
     * 添加联系人右键短信发送按钮
     */
    private void addSMSPopupListeners() {
        final ContactList contactList = SparkManager.getWorkspace().getContactList();

        // Add ContactList items.
        final Action inviteAllAction = new AbstractAction() {
            public void actionPerformed(ActionEvent actionEvent) {
            	if(SMSManager.isGrantSendSMS){
            		Collection<ContactItem> contacts = contactList.getActiveGroup().getContactItems();
                    Collection<ContactItem> offlienContacts = contactList.getActiveGroup().getOfflineContacts();
                    contacts.addAll(offlienContacts);
                    final ContactList contactList = SparkManager.getWorkspace().getContactList();
                    List<String> jids = new ArrayList<String>();
                    for (Object item1 : contacts) {
                        ContactItem item = (ContactItem) item1;
                        ContactGroup contactGroup = contactList.getContactGroup(item.getGroupName());
                        contactGroup.clearSelection();
                        jids.add(item.getJID());
                    } 
                    smsManager.handleSMSDialog(jids);
				}else{
					JOptionPane.showMessageDialog(contactList, "您未被授予发短信的权限,请通知管理员配置.", "权限不足", JOptionPane.INFORMATION_MESSAGE);
				}
            }
        };

        inviteAllAction.putValue(Action.NAME, Res.getString("menuitem.sms.send.group"));
        inviteAllAction.putValue(Action.SMALL_ICON, SparkRes.getImageIcon(SparkRes.SMS_SEND_TO_GROUP));


        final Action conferenceAction = new AbstractAction() {
            public void actionPerformed(ActionEvent actionEvent) {
            	if(SMSManager.isGrantSendSMS){
            		Collection contacts = contactList.getSelectedUsers();
                    final ContactList contactList = SparkManager.getWorkspace().getContactList();
                    List<String> jids = new ArrayList<String>();
                    for (Object item1 : contacts) {
                        ContactItem item = (ContactItem) item1;
                        ContactGroup contactGroup = contactList.getContactGroup(item.getGroupName());
                        contactGroup.clearSelection();
                        jids.add(item.getJID());
                    }
                    smsManager.handleSMSDialog(jids);
				}else{
					JOptionPane.showMessageDialog(contactList, "您未被授予发短信的权限,请通知管理员配置.", "权限不足", JOptionPane.INFORMATION_MESSAGE);
				}
            }
        };

        conferenceAction.putValue(Action.NAME, Res.getString("menuitem.sms.send"));
        conferenceAction.putValue(Action.SMALL_ICON, SparkRes.getImageIcon(SparkRes.SMS_SEND_TO_ONE_16x16));


        contactList.addContextMenuListener(new ContextMenuListener() {
            public void poppingUp(Object component, JPopupMenu popup) {
                Collection col = contactList.getSelectedUsers();
                if (component instanceof ContactGroup) {
                    popup.add(inviteAllAction);
                }
                else if (component instanceof ContactItem && col.size() > 0) {
                    popup.add(conferenceAction);
                }
            }

            public void poppingDown(JPopupMenu popup) {

            }

            public boolean handleDefaultAction(MouseEvent e) {
                return false;
            }
        });

        // Add to Actions Menu
        final JMenu actionsMenu = SparkManager.getMainWindow().getMenuByName(Res.getString("menuitem.actions"));
        actionsMenu.add(conferenceAction);
    }

    public void shutdown() {

    }

    public boolean canShutDown() {
        return false;
    }

    public void uninstall() {

    }
    
	@Override
	public void vcardChanged(VCard vcard) {
		//用户修改个人手机号码同步更新短信机中的号码
		String phone = vcard.getPhoneWork("CELL");
		if(phone!=null && !"".equals(phone)){
			String reg = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
			boolean b = phone.matches(reg);
			if(b){
				smsManager.synUpdateUserPhone(phone);
			}
		}
	}


}
